/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.etrs.formathlon.entity.formation;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.Version;
import net.etrs.formathlon.entity.infrastructure.Salle;
import net.etrs.formathlon.entity.utilisateur.Personnel;
import net.etrs.formathlon.entity.utils.ComparableEvenThoughUnpersisted;
import net.etrs.formathlon.persistance.utils.JpaRequestNames;

/**
 * Entité symbolisant une session de formation.
 * @author OPIF
 */
@Entity
@NamedQueries({
    @NamedQuery(name = JpaRequestNames.LISTE_SESSION_SUIVANT_ETAT,
    query = "SELECT object(s) FROM Session s WHERE s.archive=false AND s.etat=:unEtat"),
    @NamedQuery(name = JpaRequestNames.LISTE_SESSION_DISPENSEES,
    query = "SELECT object(s) FROM Session s WHERE s.archive=false AND s.instructeur=:instructeur")
})
@Table(name = "SessionForm")
public class Session extends ComparableEvenThoughUnpersisted<Session> {

    private static final long serialVersionUID = 1L;
    
    /**
     * Identifiant.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    /**
     * Formation dispensé durant la session.
     */
    @ManyToOne
    private Formation formation;
    
    /**
     * Date de debut de la session.
     */
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dateDebut;
    
    /**
     * Date de fin de la session.
     */
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dateFin;
    
    /**
     * Nombre minimum de la session pour être dispensé.
     */
    private int nbPlaceMini = 1;
    
    /**
    * Nombre maximum de la session pour être dispensé.
    */
    private int nbPlaceMax = 1;
    
    /**
     * Etat de la session.
     */
    @Enumerated(EnumType.STRING)
    private EtatSession etat;
    
    /**
     * Formateur avancé qui dispensera la formation.
     */
    @ManyToOne
    private Personnel instructeur;
    
    /**
     * Liste des séances composant la session.
     */
    @OneToMany(mappedBy = "session", cascade = CascadeType.ALL)
    private List<Seance> listSeance = new ArrayList<Seance>();
    
    /**
     * Salle ou se déroulera la formation?
     */
    @ManyToOne
    private Salle salle;
    /**
     * Liste des inscriptions de formateur à cette session.
     */
    @OneToMany(mappedBy = "session")
    private List<Inscription> listInscription = new ArrayList<Inscription>();
    /**
     * Gestion de la concurrence d'accès.
     */
    @Version
    private int version;
    private boolean archive;

    @Override
    public Long getId() {
        return id;
    }

    /**
     * Setter de l'id.
     * @param id 
     */
    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return String.format("Session id=%d", id);
    }

    /**
     * @return the formation
     */
    public Formation getFormation() {
        return formation;
    }

    /**
     * @param formation the formation to set
     */
    public void setFormation(Formation formation) {
        this.formation = formation;
    }

    /**
     * @return the dateDebut
     */
    public Date getDateDebut() {
        return dateDebut;
    }

    /**
     * @param dateDebut the dateDebut to set
     */
    public void setDateDebut(Date dateDebut) {
        this.dateDebut = dateDebut;
    }

    /**
     * @return the dateFin
     */
    public Date getDateFin() {
        return dateFin;
    }

    /**
     * @param dateFin the dateFin to set
     */
    public void setDateFin(Date dateFin) {
        this.dateFin = dateFin;
    }

    /**
     * @return the nbPlaceMini
     */
    public int getNbPlaceMini() {
        return nbPlaceMini;
    }

    /**
     * @param nbPlaceMini the nbPlaceMini to set
     */
    public void setNbPlaceMini(int nbPlaceMini) {
        this.nbPlaceMini = nbPlaceMini;
    }

    /**
     * @return the nbPlaceMax
     */
    public int getNbPlaceMax() {
        return nbPlaceMax;
    }

    /**
     * @param nbPlaceMax the nbPlaceMax to set
     */
    public void setNbPlaceMax(int nbPlaceMax) {
        this.nbPlaceMax = nbPlaceMax;
    }

    /**
     * @return the etat
     */
    public EtatSession getEtat() {
        return etat;
    }

    /**
     * @param etat the etat to set
     */
    public void setEtat(EtatSession etat) {
        this.etat = etat;
    }

    /**
     * @return the instructeur
     */
    public Personnel getInstructeur() {
        return instructeur;
    }

    /**
     * @param instructeur the instructeur to set
     */
    public void setInstructeur(Personnel instructeur) {
        this.instructeur = instructeur;
    }

    /**
     * @return the listSeance
     */
    public List<Seance> getListSeance() {
        return listSeance;
    }

    /**
     * @param listSeance the listSeance to set
     */
    public void setListSeance(List<Seance> listSeance) {
        this.listSeance = listSeance;
    }

    /**
     * @return the salle
     */
    public Salle getSalle() {
        return salle;
    }

    /**
     * @param salle the salle to set
     */
    public void setSalle(Salle salle) {
        this.salle = salle;
    }

    /**
     * @return the version
     */
    public int getVersion() {
        return version;
    }

    /**
     * @param version the version to set
     */
    public void setVersion(int version) {
        this.version = version;
    }

    /**
     * @return the listInscription
     */
    public List<Inscription> getListInscription() {
        return listInscription;
    }

    /**
     * @param listInscription the listInscription to set
     */
    public void setListInscription(List<Inscription> listInscription) {
        this.listInscription = listInscription;
    }

    /**
     * Etat de la session.
     */
    public enum EtatSession {

        /**
         * Pas encore ouverte à l'inscription.
         */
        CREATION("En création"),
        /**
         * Ouverte à l'inscription.
         */
        OUVERT("Ouverte"),
        /**
         * Fermée à l'inscription.
         */
        FERME("Fermée"),
        /**
         * Vérrouillée au désistement, par l'instructeur.
         */
        VERROUILLE("Verrouillée"),
        /**
         * Session terminée par l'instructeur.
         */
        TERMINE("Terminée");
        private String libelle;
        public static String[] stringValues;

        /**
         * constructeur par defaut de l'état.
         * @param libelle 
         */
        EtatSession(String libelle) {
            this.libelle = libelle;
        }

        /**
         * 
         * @return le libellé de l'état
         */
        public String getLibelle() {
            return this.libelle;
        }

        /**
         * 
         * @return La liste des libéllé dans un tableau de string.
         */
        
        public static String[] stringValues() {
              if (stringValues == null) {
                StringBuilder liste = new StringBuilder();
                for (EtatSession etat : values()) {
                    if (liste.length() != 0) {
                        liste.append("/");
                    }
                    liste.append(etat.libelle);
                }
                stringValues = liste.toString().split("/");
            }
            return stringValues;
        }
    }

    /**
     * @return the archive
     */
    @Override
    public boolean isArchive() {
        return archive;
    }

    /**
     * @param archive the archive to set
     */
    @Override
    public void setArchive(boolean archive) {
        this.archive = archive;
    }
}
